package com.heking.zplayer.qlyopen;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.View;

import com.cmcc.qlyopensdk.init.impl.QlyOpenSdk;
import com.cmcc.qlyopensdk.player.OnAudioCallListener;
import com.cmcc.qlyopensdk.player.OnPlayerListener;
import com.cmcc.qlyopensdk.player.constant.AudioState;
import com.cmcc.qlyopensdk.player.constant.PlayStatus;
import com.cmcc.qlyopensdk.player.constant.StorageType;
import com.cmcc.qlyopensdk.player.impl.QlyOpenSdkPlayer;
import com.cmcc.qlyopensdk.vo.response.CameraAbility;

import java.util.List;

import androidx.annotation.NonNull;


/**
 * @Author: zhoug
 * @Date: 2024-11-05
 * @Description:
 */
public class QlyPlayer extends BaseQlyPlayer {
    private static final String TAG = ">>>QlyPlayer";
    private QlyOpenSdkPlayer mPlayer;
    protected boolean isTalking = false;

    private boolean isConnect = false;//是否连接设备
    private QlyCameraAbility mQlyCameraAbility;//设备能力
    private boolean autoGetAbility = false;
    private boolean autoGetSettings = false;
    private QlyCameraSetting mQlyCameraSetting;

    public QlyPlayer(Context context) {
        super(context);
    }


    /**
     * 连接设备
     *
     * @param callback
     */
    protected void connect(@NonNull Callback<String> callback) {
        Log.d(TAG, "connect:连接设备:" + mDeviceId);
        QLYApi.connectCamera(mContext, getMacByDeviceId(), callback);
    }


    public void initPlayer() {
        Log.d(TAG, "initPlayer:初始化播放器");
        mPlayer = new QlyOpenSdkPlayer(mContext, getMacByDeviceId());
        mPlayer.setMediaCodecEnabled(true); //设置是否硬解，默认true
        mPlayer.setOnPlayerListener(new OnPlayerListener() {
            @Override
            public void onStateChanged(int state, int code) {
                switch (state) {
                    case PlayStatus.STATE_IDLE://空闲
                        callStatusChange(IQlyPlayer.STATE_IDLE);
                        break;
                    case PlayStatus.STATE_PREPARING://资源准备

                        break;
                    case PlayStatus.STATE_PREPARED://资源准备好了
                        callStatusChange(IQlyPlayer.STATE_PREPARED);
                        break;
                    case PlayStatus.STATE_BUFFERING://缓冲

                        break;
                    case PlayStatus.STATE_BUFFERED://缓冲完成

                        break;
                    case PlayStatus.STATE_PLAYING://播放
                        setMute();
                        callStatusChange(IQlyPlayer.STATE_PLAYING);
                        break;
                    case PlayStatus.STATE_PAUSED://暂停
                        callStatusChange(IQlyPlayer.STATE_PAUSE);
                        break;
                    case PlayStatus.STATE_STOPED://停止
                        callStatusChange(IQlyPlayer.STATE_IDLE);
                        break;
                    case PlayStatus.STATE_COMPLETED://播放完成
                        callStatusChange(IQlyPlayer.STATE_ENDED);
                        break;
                    case PlayStatus.STATE_CONTROL_ERROR://控制错误
                        callError(PlayError.STATE_CONTROL_ERROR, "控制错误");
                        break;
                    case PlayStatus.STATE_ERROR://错误
                        callError(PlayError.UNKNOWN_ERROR, "错误代码:" + code);
                        break;
                }
            }

            /**
             * 当视频开始播放时回调视频真实尺寸
             * @param width
             * @param height
             */
            @Override
            public void onVideoSizeChanged(int width, int height) {
                if (mPlayListener != null) {
                    ThreadUtils.runMainThread(() -> mPlayListener.onVideoSizeChanged(width, height));
                }
            }

            /**
             *
             * 播放完成
             */
            @Override
            public void onPlaybackComplete() {
                Log.d(TAG, "onPlaybackComplete:播放完成");
                callStatusChange(IQlyPlayer.STATE_ENDED);
            }
        });
        mPlayer.setOnOnAudioCallListener(onAudioCallListener);

        View playerView = mPlayer.getPlayerView();
        mPlayViewGroup.removeAllViews();
        mPlayViewGroup.addView(playerView);
    }

    private OnAudioCallListener onAudioCallListener = new OnAudioCallListener() {
        @Override
        public void onAudioStateChanged(int state) {
            switch (state) {
                case AudioState.AUDIO_STATE_AVAILABLE://可进行通话
                    Log.d(TAG, "可进行通话:");
                    break;
                case AudioState.AUDIO_STATE_UNAVAILABLE://不可进行通话
                    Log.e(TAG, "不可进行通话:");
                    if (isTalking) {
                        callTalking(OnTalkListener.FAILED, "不可进行通话");
                        stopVoiceTalk();
                    }
                    break;
                case AudioState.AUDIO_STATE_ERROR_BUSY://别人正在通话导致断开
                    Log.e(TAG, "别人正在通话导致断开");
                    if (isTalking) {
                        callTalking(OnTalkListener.EXCEPTION, "别人正在通话导致断开");
                        stopVoiceTalk();
                    }
                    break;
                case AudioState.AUDIO_STATE_ERROR_STOP://通话异常断开
                    Log.e(TAG, "通话异常断开:");
                    if (isTalking) {
                        callTalking(OnTalkListener.EXCEPTION, "通话异常断开");
                        stopVoiceTalk();
                    }
                    break;
            }
        }
    };

    @Override
    public boolean isPlaying() {
        return super.isPlaying() && mPlayer != null && mPlayer.isPlaying();
    }

    /**
     * 开始播放,每次都是重新加载资源播放,可以播放新的url
     */
    @Override
    public void startPlay() {
        callStatusChange(IQlyPlayer.STATE_START);
        if (isConnect) {
            if (mPlayer == null) {
                initPlayer();
                start();
            } else {
                if (mPlayState == IQlyPlayer.STATE_PAUSE) {
                    resumePlay();
                } else {
                    start();
                }
            }
        } else {
            connect(new Callback<String>() {
                @Override
                public void onSuccess(String s) {
                    isConnect = true;
                    if (autoGetAbility) {
                        getDeviceAbility();
                    }
                    if (autoGetSettings) {
                        getSettings();
                    }
                    if (mPlayer == null) {
                        initPlayer();
                    }
                    start();
                }

                @Override
                public void onError(String error) {
                    isConnect = false;
                    if (error != null && error.contains("token无效")) {
                        callError(PlayError.TOKEN_EXPIRE, "token无效");
                    } else {
                        callError(PlayError.CONNECT_ERROR, error);
                    }
                }
            });
        }
    }

    private void start() {
        if (mPlayer != null) {
//          new Thread(()->{
            Log.d(TAG, "start:开始播放");
            try {
                mPlayer.prepare();
                mPlayer.start();
            } catch (Exception e) {
                e.printStackTrace();
                callError(PlayError.UNKNOWN_ERROR, e.getMessage());
            }
            setMute();
//          }).start();
        }
    }

    /**
     * 停止播放,会释放加载的媒体和资源
     */
    @Override
    public void stopPlay() {
        pausePlay();
    }

    /**
     * 如果正在播放则暂停播放,否则调用{@link #stopPlay()}停止播放
     */
    @Override
    public void pausePlay() {
        if (mPlayer != null) {
            Log.d(TAG, "pause:暂停播放");
            callStatusChange(IQlyPlayer.STATE_PAUSE);
            mPlayer.pause();
        }
    }

    /**
     * 如果暂停了或者资源已经准备好了则播放,否则{@link #startPlay()}重新开始播放
     */
    @Override
    public void resumePlay() {
        if (mPlayer != null) {
            Log.d(TAG, "pause:恢复播放");
            mPlayer.resume();
        }
    }

    @Override
    public void setMute(boolean mute) {
        super.setMute(mute);
        setMute();
    }

    protected void setMute() {
        if (mPlayer != null) {
            mPlayer.setMute(mMute);
        }
    }

    /**
     * 释放资源,注意请把所有setXXX的数据设置为空
     */
    @Override
    public void release() {
        Log.d(TAG, "release:释放资源");
        mQlyCameraAbility = null;
        callStatusChange(IQlyPlayer.STATE_IDLE);
        if (mPlayer != null) {
            mPlayer.release();
            mPlayer = null;
        }
        if (isConnect) {
            QLYApi.disconnect();
            isConnect = false;
        }
    }

    /**
     * 开启对讲
     */
    @Override
    public void startVoiceTalk() {
        if (mPlayer != null) {
            isTalking = true;
            if (isMute()) {
                setMute(false);
            }
            Log.d(TAG, "startVoiceTalk:开启对讲");
            callTalking(OnTalkListener.SUCCESS, "正在开启对讲");
            mPlayer.startAudio(mQlyCameraAbility != null && mQlyCameraAbility.supportDuplexAudioTalk());
        }
    }

    /**
     * 停止对讲
     */
    @Override
    public void stopVoiceTalk() {
        if (mPlayer != null) {
            isTalking = false;
            Log.d(TAG, "startVoiceTalk:停止对讲");
            callTalking(OnTalkListener.CLOSE, "结束对讲");
            mPlayer.stopAudio();
        }
    }

    public void capturePicture(@NonNull String path) {
        if (mPlayer != null) {
            Bitmap bitmap = null;
            try {
                bitmap = mPlayer.screenShot();
            } catch (Exception e) {
                Log.e(TAG, "capturePicture:"+e.getMessage());
                if (mCapturePictureListener != null) {
                    mCapturePictureListener.onCapturePictureResult(false, path);
                }
                return;
            }
            if (bitmap != null) {
                final Bitmap temp = bitmap;
                ThreadUtils.getExecutorService().execute(() -> {
                    boolean success = Utils.keepBitmap(temp, 100, path);
                    ThreadUtils.runMainThread(() -> {
                        Utils.scannerFile(mContext, path);
                        if (mCapturePictureListener != null) {
                            mCapturePictureListener.onCapturePictureResult(success, path);
                        }
                    });
                });
            } else {
                Log.d(TAG, "capturePicture:bitmap is null");
                ThreadUtils.runMainThread(() -> {
                    if (mCapturePictureListener != null) {
                        mCapturePictureListener.onCapturePictureResult(false, path);
                    }
                });
            }
        }
    }



    /**
     * 是否正在对讲
     *
     * @return
     */
    @Override
    public boolean isTalking() {
        return isTalking;
    }

    /**
     * 切换为直播
     */
    public void switchToLive() {
        if (mPlayer != null) {
            mPlayer.switchToLive();
        }
    }

    /**
     * 设置回放
     * 在选择了某个时间点后调用如下方法进行播放
     * 注意需要有数据的回放片段才能回放
     *
     * @param time 回放位置时间戳
     */
    public void seek(long time) {
        if (mPlayer != null) {
            mPlayer.seek(time);
        }
    }

    /**
     * 设置回放
     *
     * @param time        回放位置时间戳
     * @param storageType {@link QlyStorageType#CLOUD_STORAGE,QlyStorageType#SD_CARE_STORAGE}
     */
    public void seek(long time, int storageType) {
        if (mPlayer != null) {
            mPlayer.seek(time, QlyStorageType.getStorageType(storageType));
        }
    }

    /**
     * 获取当前播放的时间
     *
     * @return
     */
    public long getCurrentTime() {
        if (mPlayer != null) {
            return mPlayer.getCurrentTime();
        }
        return 0;
    }

    /**
     * 高标清切换
     */
    public void switchPlayQuality(@NonNull Callback<Integer> callback) {
        if (mQlyCameraSetting == null) return;
        int hd = mQlyCameraSetting.getHdVideo() == ZQlyOpenSdk.QUALITY_HD ? ZQlyOpenSdk.QUALITY_SD : ZQlyOpenSdk.QUALITY_HD;
        QLYApi.switchPlaybackQuality(getMacByDeviceId(), hd, new Callback<Integer>() {
            @Override
            public void onSuccess(Integer integer) {
                if (integer != -1 && mQlyCameraSetting != null) {
                    mQlyCameraSetting.setHdVideo(hd);
                }
                callback.onSuccess(integer);
            }

            @Override
            public void onError(String error) {
                callback.onError(error);
            }
        });
    }

    /**
     * 获取设备能级
     */
    public void getDeviceAbility() {
        Log.d(TAG, "获取设备能级");
        QLYApi.getDeviceAbility(getMacByDeviceId(), new Callback<CameraAbility>() {
            @Override
            public void onSuccess(CameraAbility cameraAbility) {
                mQlyCameraAbility = cameraAbility != null ? new QlyCameraAbility(cameraAbility) : null;
                if (mOnCameraAbilityChange != null) {
                    mOnCameraAbilityChange.onSuccess(mQlyCameraAbility);
                }
            }

            @Override
            public void onError(String error) {
                Log.e(TAG, "onError:获取设备能级发生错误:" + error);
                if (mOnCameraAbilityChange != null) {
                    mOnCameraAbilityChange.onError(error);
                }
            }
        });
    }

    /**
     * 获取设置信息
     */
    public void getSettings() {
        QLYApi.getSettings(getMacByDeviceId(), new Callback<QlyCameraSetting>() {
            @Override
            public void onSuccess(QlyCameraSetting qlyCameraSetting) {
                mQlyCameraSetting = qlyCameraSetting;
                if (mOnQlyCameraSettingChange != null) {
                    mOnQlyCameraSettingChange.onSuccess(mQlyCameraSetting);
                }
            }

            @Override
            public void onError(String error) {
                if (mOnQlyCameraSettingChange != null) {
                    mOnQlyCameraSettingChange.onError(error);
                }
            }
        });
    }

    /**
     * 获取云存储回放数据列表
     *
     * @param startTime
     * @param endTime
     * @param callback
     */
    public void getTimelineSectionList(long startTime, long endTime, @NonNull Callback<List<RecordSegment>> callback) {
        QLYApi.getTimelineSectionList(getMacByDeviceId(), startTime, endTime, callback);
    }

    /**
     * 获取SD卡回放数据列表
     *
     * @param startTime
     * @param endTime
     * @param callback
     */
    public void getSdcardTimelineSectionList(long startTime, long endTime, @NonNull Callback<List<RecordSegment>> callback) {
        QLYApi.getSdcardTimelineSectionList(getMacByDeviceId(), startTime, endTime, callback);
    }


    protected String getMacByDeviceId() {
        return ZQlyOpenSdk.getMacByDeviceId(mDeviceId);
    }

    public void setAutoGetAbility(boolean autoGetAbility) {
        this.autoGetAbility = autoGetAbility;
    }

    public void setAutoGetSettings(boolean autoGetSettings) {
        this.autoGetSettings = autoGetSettings;
    }
}
